package com.dsteiner.xelavos.client.controller;

import static com.dsteiner.widgets.client.util.Validator.PSWD_VALIDATOR;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import com.dsteiner.widgets.client.Widgets.HTMLExt;
import com.dsteiner.widgets.client.Widgets.IButton;
import com.dsteiner.widgets.client.Widgets.IHTML;
import com.dsteiner.widgets.client.Widgets.IImage;
import com.dsteiner.widgets.client.Widgets.ILazyWidget;
import com.dsteiner.widgets.client.Widgets.IWidget;
import com.dsteiner.widgets.client.Widgets.WidgetListenerAdapter;
import com.dsteiner.widgets.client.event.DataUpdateEvent;
import com.dsteiner.widgets.client.event.Event;
import com.dsteiner.widgets.client.event.EventListener;
import com.dsteiner.widgets.client.event.EventManager;
import com.dsteiner.widgets.client.event.EventManagerImpl;
import com.dsteiner.widgets.client.event.MessageEvent;
import com.dsteiner.widgets.client.model.FileUploadModel;
import com.dsteiner.widgets.client.model.PrefilledTextBoxModel;
import com.dsteiner.widgets.client.rpc.CrudResult;
import com.dsteiner.widgets.client.util.ValidationResults;
import com.dsteiner.xelavos.client.constants.Constants;
import com.dsteiner.xelavos.client.domain.User;
import com.dsteiner.xelavos.client.model.AuthenticationModel;
import com.dsteiner.xelavos.client.model.MyProfileModel;
import com.dsteiner.xelavos.client.rpc.DataService;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class MyProfileController {

	private AuthenticationModel authenticationModel;
	private IImage mainImage;
	private IImage userNotAvailableImage;
	private MyProfileModel myProfileModel;
	private FileUploadModel fileUploadModel;
	private PrefilledTextBoxModel passwordTextBoxModel;
	private PrefilledTextBoxModel passwordConfirmTextBoxModel;

	public void registerAuthenticationModel(AuthenticationModel authenticationModel) {
		this.authenticationModel = authenticationModel;
		authenticationModel.addPropertyChangeListener("user", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				updateUserInfo();
			}
		});
	}

	public void registerEventManager(EventManager eventManager) {
		eventManager.registerListener(DataUpdateEvent.class, new EventListener(){
			public void onEvent(Event event) {
				DataUpdateEvent dataUpdateEvent = (DataUpdateEvent) event;
				Object object = dataUpdateEvent.getObject();
				if(object instanceof User)
					updateUserInfo();
			}
		});

	}

	public void registerFileUploadModel(final FileUploadModel fileUploadModel) {
		this.fileUploadModel = fileUploadModel;
		fileUploadModel.addPropertyChangeListener("submitResult", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				String id = fileUploadModel.getSubmitResult();
				User user = authenticationModel.getUser();
				user.setImageId(id);
				EventManagerImpl.getInstance().fireEvent(new DataUpdateEvent(user));
			}
		});
		fileUploadModel.addPropertyChangeListener("submited", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				System.out.println(".propertyChange()");
			}
		});
	}

	public void registerMainImage(IImage mainImage) {
		this.mainImage = mainImage;
	}

	public void registerMyProfileModel(MyProfileModel myProfileModel) {
		this.myProfileModel = myProfileModel;
	}

	public void registerMyProfileWidget(ILazyWidget myProfileWidget) {
		myProfileWidget.addWidgetListener(new WidgetListenerAdapter(){
			@Override
			public void onAttach(IWidget widget) {
				updateUserInfo();
			}
		});
	}

	public void registerUserNotAvailableImage(IImage userNotAvailableImage) {
		this.userNotAvailableImage = userNotAvailableImage;
	}

	private void updateUserInfo() {
		User user = authenticationModel.getUser();
		if(user == null)
			return;
		
		String imageId = user.getImageId();
		String fileUploadUrl = Constants.Util.getFileUploadUrl(user);
		fileUploadModel.setActionUrl(fileUploadUrl);
		mainImage.setVisible(imageId != null);
		userNotAvailableImage.setVisible(imageId == null);
		if(imageId != null)
			mainImage.setUrl(Constants.Util.getImageUrl(imageId));
	}

	public void registerChangePasswordButton(IButton changePasswordButton) {
		changePasswordButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				String passwordConfirm = passwordConfirmTextBoxModel.isEdited() ? passwordConfirmTextBoxModel.getText() : null;
				String password = passwordTextBoxModel.isEdited() ? passwordTextBoxModel.getText() : null;
				ValidationResults results = new ValidationResults()
				.add(PSWD_VALIDATOR.validate(password, passwordConfirm));
				
				if(!results.isEmpty()){
					String validationMsg = results.getMessage();
					EventManagerImpl.getInstance().fireEvent(new MessageEvent(validationMsg));
					return;
				}
				
				User user = authenticationModel.getUser();
				EventManagerImpl.getInstance().fireEvent(new MessageEvent("actualizando la contraseña...", MessageEvent.TYPE_ACTIVITY));
				DataService.Util.getInstance().updatePassword(user, password, new AsyncCallback<CrudResult<User>>(){
					public void onFailure(Throwable arg0) {
						arg0.printStackTrace();
						EventManagerImpl.getInstance().fireEvent(new MessageEvent("contraseña no pudo actualizarse - intente otra vez"));
					}
					public void onSuccess(CrudResult<User> arg0) {
						EventManagerImpl.getInstance().fireEvent(new MessageEvent("contraseña actualizado exitosamente", 
								MessageEvent.TYPE_INFO));
					}
				});
			}
		});
	}

	public void registerPasswordTextBoxModel(PrefilledTextBoxModel passwordTextBoxModel) {
		this.passwordTextBoxModel = passwordTextBoxModel;
	}

	public void registerConfirmPasswordTextBoxModel(PrefilledTextBoxModel confirmPasswordTextBoxModel) {
		this.passwordConfirmTextBoxModel = confirmPasswordTextBoxModel;
	}
}
